
#include <string>
#include "gameState.h"

Move::Move(char sr, char sc, char dr, char dc, MoveType t)
{
    source_row = sr;
    source_col = sc;
    destination_row = dr;   
    destination_col = dc;
    type = t;
}


std::ostream& operator<<(std::ostream &os, const Move &move)
{
      os << "from: " << char('a'+move.source_col) << 8-int(move.source_row);
      os << " to: "  << char('a'+move.destination_col) << 8-int(move.destination_row);
      os << " type: " << move.type << "\n";
      
      return os;
}

bool Move::operator==(const Move& m) const
{
    if(source_row      == m.source_row      && source_col      == m.source_col      &&
       destination_row == m.destination_row && destination_col == m.destination_col &&
       type == m.type)
       return true;    
    
    return false;
}

  
void Move::print() const
{
    std::cout << "from: " << (8-int(source_row)) << " " << 'a' + source_col;
    std::cout << " to: "  << (8-int(destination_row)) << " " << 'a' + destination_col;
    std::cout << " type: " << type << "\n";
}

void GameState::print()
{
    std::cout << "Current player: " << ((round == WHITE) ? "WHITE" : "BLACK") << "\n";
    
    for(int i = 0; i < 8; i++)
    {
        std::cout << (8-i) <<" ";
        for(int j = 0; j < 8; j++)
            std::cout << Util::pieceToString(this->board[i][j]) << " ";   
        std::cout << "\n";
    }
    std::cout << "   a   b   c   d   e   f   g   h\n";
    
    std::cout << "PlayerCheck: " << isPlayerUnderCheck << "\n";
    std::cout << "EnemyCheck: "  << isEnemyUnderCheck << "\n";
    std::cout << "LosingState: "  << isLosingState << "\n";
    
}
        
bool GameState::inBoard(int r, int c)
{
    if(r <= 7 && r >= 0 && c <= 7 && c >= 0)   
        return true;
    return false;
}
        

void GameState::merge(std::vector<Move>& base, std::vector<Move>& toMerge)
{
    for(int i = 0; i < toMerge.size(); i++)
        base.push_back(toMerge[i]);
}

Colour Util::pieceColour(FieldValue fv)
{
    if(fv >= BLACK_PAWN && fv <= BLACK_KING)   
        return BLACK;
    else if(fv >= WHITE_PAWN && fv <= WHITE_KING)
        return WHITE;
    else 
        return NONE;
}

std::string Util::pieceToString(FieldValue fv)
{
    switch( fv )
    {
        case BLACK_PAWN:
            return "B-P";
        case WHITE_PAWN:
            return "W-P";
        case BLACK_KNIGHT:
            return "B-K";
        case WHITE_KNIGHT:
            return "W-K";
        case BLACK_BISHOP:
            return "B-B";
        case WHITE_BISHOP:
            return "W-B";
        case BLACK_ROOK:
            return "B-R";
        case WHITE_ROOK:
            return "W-R";
        case BLACK_QUEEN:
            return "B-Q";
        case WHITE_QUEEN:
            return "W-Q";
        case BLACK_KING:
            return "BKI";
        case WHITE_KING:
            return "WKI";
        case EMPTY:
            return "---";
    }
}

Colour Util::opposite(Colour c)
{
    if(c == BLACK)
        return WHITE;
    else
        return BLACK;   
}

unsigned char*** Util::allocateInfoTable()
{
    unsigned char*** info = new unsigned char**[2];
    info[0] = new unsigned char*[8];
    info[1] = new unsigned char*[8];
    for(int i = 0; i < 8; i++)
    {
        info[0][i] = new unsigned char[8];
        info[1][i] = new unsigned char[8];
        for(int j = 0; j < 8; j++)
        {
            info[0][i][j] = 0; 
            info[1][i][j] = 0;
        }
    }
    return info;
}

void Util::deleteInfoTable(unsigned char*** info)
{
    for(int i = 0; i < 8; i++)
    {
        delete info[0][i];
        delete info[1][i];
        info[0][i] = 0;
        info[1][i] = 0;
    }
    delete info[0];
    delete info[1];
    info[0] = 0;
    info[1] = 0;
    info = 0;
}
